package 链表题目;

import 链表题目.model.ListNode;


//中间反转链表
//https://leetcode.cn/problems/reverse-linked-list-ii/description/
//给你单链表的头指针 head 和两个整数 left 和 right ，其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点，返回 反转后的链表 。
class 反转中间链表 {
    public ListNode reverseBetween(ListNode head, int left, int right) {
        ListNode dummyNode = new ListNode(-1);
        dummyNode.next = head;
        // 1 -> 2 -> 3 -> 4 -> 5
        // left = 2  right = 4
        // 1  | 2 -> 3 -> 4 | 5
        // 1  | 4 -> 3 -> 2 | 5
        // 1 -> 4 -> 3 -> 2 -> 5
        ListNode pre = dummyNode;
        // 第 1 步：从虚拟头节点走 left - 1 步，来到 left 节点的前一个节点
        // 建议写在 for 循环里，语义清晰
        for (int i = 0; i < left - 1; i++) {
            pre = pre.next;
        }

        // 第 2 步：从 pre 再走 right - left + 1 步，来到 right 节点
        ListNode rightNode = pre;
        for (int i = 0; i < right - left + 1; i++) {
            rightNode = rightNode.next;
        }

        // 第 3 步：切断出一个子链表（截取链表）
        ListNode leftNode = pre.next;
        ListNode curr = rightNode.next;

        // 注意：切断链接
        pre.next = null;
        rightNode.next = null;

        // 第 4 步：同第 206 题，反转链表的子区间
        reverseLinkedList(leftNode);

        // 第 5 步：接回到原来的链表中
        pre.next = rightNode;
        leftNode.next = curr;
        return dummyNode.next;
    }

    private void reverseLinkedList(ListNode head) {
        // 1 -> 2 -> 3
        ListNode pre = null; // 前驱
        ListNode cur = head;  //当前节点  1
        ListNode next = cur.next; // 后继 2
        while (cur != null) {
            cur.next = pre; // 1 -> null    2 -> 1 -> null  3 -> 2 -> 1 -> null
            pre = cur; // 1 -> null   2 -> 1 -> null  3 -> 2 -> 1 -> null
            cur = next;// 2  3  null
            if (next != null) {
                next = next.next; // 2   3
            }
        }
    }


//    public static void main(String[] args) {
//        Solution reverseBetween = new Solution();
//        ListNode head = new ListNode(1, null);
//        head.next = new ListNode(2, null);
//        head.next.next = new ListNode(3, null);
//        head.next.next.next = new ListNode(4, null);
//        head.next.next.next.next = new ListNode(5, null);
//        ListNode listNode = reverseBetween.reverseBetween(head, 2, 4);
//
//    }
}
